home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Src / submit / submit_chk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  11.3 KB  |  479 lines

  1. /* submit_chk.c: checks done by submit */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Src/submit/RCS/submit_chk.c,v 6.0 1991/12/18 20:28:02 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Src/submit/RCS/submit_chk.c,v 6.0 1991/12/18 20:28:02 jpo Rel $
  9.  *
  10.  * $Log: submit_chk.c,v $
  11.  * Revision 6.0  1991/12/18  20:28:02  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include "head.h"
  19. #include "q.h"
  20. #include "dr.h"
  21.  
  22. /* -- externals -- */
  23. extern char        *cont_p22;
  24. extern void        message_failure();
  25.  
  26.  
  27. /* -- local routines -- */
  28. void            check_conversions();
  29. void            check_crits();
  30. void            check_dr_crits();
  31. int            check_crit();
  32. static void        check_extn_crits();
  33. static void        check_q_crits();
  34. static void        check_rrinfo_crits();
  35.  
  36.  
  37.  
  38.  
  39. /* ---------------------  Begin  Routines  -------------------------------- */
  40.  
  41.  
  42.  
  43.  
  44. int check_crit (this, mask, qp, adr, str)
  45. char        this,
  46.         mask;
  47. Q_struct    *qp;
  48. ADDR        *adr;    /* if NULLADDR and fail, fail total message */
  49. char        *str;
  50. {
  51.     char    buf[BUFSIZ];
  52.     if (this != 0 && (this & (~mask))) {
  53.         /* fail on critical */
  54.         (void) sprintf (buf, "Unsupported criticality of '%s'",
  55.                 str);
  56.         if (adr == NULLADDR)
  57.             message_failure (DRR_UNABLE_TO_TRANSFER,
  58.                      DRD_UNSUPPORTED_CRITICAL_FUNCTION,
  59.                      buf);
  60.         else {
  61.             if (adr -> ad_status == AD_STAT_PEND) {
  62.                 adr -> ad_status = AD_STAT_DRREQUIRED;
  63.                 adr -> ad_reason = DRR_UNABLE_TO_TRANSFER;
  64.                 adr -> ad_diagnostic = DRD_UNSUPPORTED_CRITICAL_FUNCTION;
  65.                 adr -> ad_add_info = strdup(buf);
  66.             }
  67.         }
  68.         return NOTOK;
  69.     }
  70.     return OK;
  71. }
  72.  
  73.  
  74.  
  75.  
  76. void check_crits (qp)
  77. register Q_struct     *qp;
  78. {
  79.     ADDR    *ix = qp -> Raddress;
  80.     
  81.     check_extn_crits (qp, qp -> per_message_extensions, 
  82.               "per_message_extensions");
  83.     while (ix != NULLADDR) {
  84.         if (ix -> ad_status == AD_STAT_PEND)
  85.             check_q_crits (qp, ix);
  86.         ix = ix -> ad_next;
  87.     }
  88. }
  89.  
  90.  
  91.  
  92.  
  93. void check_dr_crits (qp, dr)
  94. Q_struct *qp;
  95. DRmpdu    *dr;
  96. {    
  97.     Rrinfo    *ix = dr -> dr_recip_list;
  98.  
  99.     check_extn_crits (qp, dr->dr_per_envelope_extensions,
  100.               "per_envelope_extensions");
  101.     check_extn_crits (qp, dr -> dr_per_report_extensions,
  102.               "per_report_extensions");
  103.     
  104.     while (ix != (Rrinfo *) NULL) {
  105.         check_rrinfo_crits (qp, dr, ix);
  106.         ix = ix -> rr_next;
  107.     }
  108. }
  109.     
  110.  
  111.  
  112.  
  113. void check_conversions (qp)
  114. register Q_struct    *qp;
  115. {
  116.     ADDR    *ix;
  117.     LIST_RCHAN    *chan;
  118.     int        cont;
  119.     if (qp -> implicit_conversion_prohibited == TRUE) {
  120.         ix = qp -> Raddress;
  121.         
  122.         while (ix != NULLADDR) {
  123.             if (ix -> ad_status == AD_STAT_PEND
  124.                 && ix -> ad_fmtchan != NULLIST_RCHAN) {
  125.                 chan = ix -> ad_fmtchan;
  126.                 cont = TRUE;
  127.                 while (cont == TRUE
  128.                        && chan != NULLIST_RCHAN) {
  129.                     switch (chan -> li_chan -> ch_conversion) {
  130.                         case CH_CONV_CONVERT:
  131.                         case CH_CONV_WITHLOSS:
  132.                         /* fail this recipient */
  133.                         ix -> ad_status = AD_STAT_DRREQUIRED;
  134.                         ix -> ad_reason = DRR_UNABLE_TO_TRANSFER;
  135.                         ix -> ad_diagnostic = DRD_CONVERSION_PROHIBITED;
  136.                         ix -> ad_add_info = strdup("Conversion of this message was prohibited");
  137.                         cont = FALSE;
  138.                         default:
  139.                         break;
  140.                     }
  141.                     chan = chan -> li_next;
  142.                 }
  143.             }
  144.             ix = ix -> ad_next;
  145.         }
  146.     }
  147.     if (qp -> conversion_with_loss_prohibited == TRUE) {
  148.         ix = qp -> Raddress;
  149.         while (ix != NULLADDR) {
  150.             if (ix -> ad_status == AD_STAT_PEND
  151.                 && ix -> ad_fmtchan != NULLIST_RCHAN) {
  152.                 chan = ix -> ad_fmtchan;
  153.                 cont = TRUE;
  154.                 while (cont == TRUE
  155.                        && chan != NULLIST_RCHAN) {
  156.                     if (chan -> li_chan -> ch_conversion == CH_CONV_WITHLOSS) {
  157.                         /* fail this recipient */
  158.                         ix -> ad_status = AD_STAT_DRREQUIRED;
  159.                         ix -> ad_reason = DRR_UNABLE_TO_TRANSFER;
  160.                         ix -> ad_diagnostic = DRD_CONVERSION_PROHIBITED;
  161.                         ix -> ad_add_info = strdup("Conversion of this message would incur loss of information");
  162.                         cont = FALSE;
  163.                     }
  164.                     chan = chan -> li_next;
  165.                 }
  166.             }
  167.             ix = ix -> ad_next;
  168.         }
  169.     }
  170. }
  171.  
  172.  
  173.  
  174.  
  175. /* ---------------------  Static Routines  -------------------------------- */
  176.  
  177.  
  178.  
  179.  
  180. static void check_rrinfo_crits (qp, dr, rr)
  181. Q_struct *qp;
  182. register DRmpdu    *dr;
  183. register Rrinfo    *rr;
  184. {
  185.     char     mask = CRITICAL_SUBMISSION;
  186.     ADDR    *adr = qp -> Raddress;
  187.     CHAN    *outchan;
  188.     X400_Extension    *ix;
  189.  
  190.     while (adr != NULLADDR && adr -> ad_no != rr -> rr_recip)
  191.         adr = adr -> ad_next;
  192.     if (adr == NULLADDR)
  193.         return;
  194.     
  195.     /* --- *** ---  
  196.     ad_outchan may be missing if msg is a x400 DR & its Recip is invalid
  197.     --- *** --- */
  198.  
  199.     if (adr -> ad_outchan == NULLIST_RCHAN ||
  200.         adr -> ad_outchan -> li_chan == NULLCHAN)
  201.             return;
  202.  
  203.     outchan = adr -> ad_outchan -> li_chan;
  204.     if (lexequ (outchan -> ch_content_out, cont_p22) == 0)
  205.         mask = mask | CRITICAL_TRANSFER | CRITICAL_DELIVERY;
  206.     else if (outchan -> ch_access == CH_MTS)
  207.         mask = mask | CRITICAL_DELIVERY;
  208.  
  209.     if (check_crit (dr -> dr_dl_history_crit, mask, qp,
  210.             adr, "dr_dl_history_crit") == NOTOK)
  211.         return;
  212.     if (check_crit (dr -> dr_reporting_dl_name_crit, mask, qp,
  213.             adr, "dr_reporting_dl_name_crit") == NOTOK)
  214.         return;
  215.     if (check_crit (dr -> dr_security_label_crit, mask, qp,
  216.             adr, "dr_security_label_crit") == NOTOK)
  217.         return;
  218.     if (check_crit (dr -> dr_reporting_mta_certificate_crit, mask, 
  219.             qp,
  220.             adr, "dr_reporting_mta_certificate_crit") == NOTOK)
  221.         return;
  222.     if (check_crit (dr -> dr_report_origin_auth_check_crit, mask, qp,
  223.             adr, "dr_report_origin_auth_check_crit") == NOTOK)
  224.         return;
  225.     if (check_crit (rr -> rr_redirect_history_crit, mask, qp,
  226.             adr, "rr_redirect_history_crit") == NOTOK)
  227.         return;
  228.     if (check_crit (rr -> rr_physical_fwd_addr_crit, mask, qp,
  229.             adr, "rr_physical_fwd_addr_crit") == NOTOK)
  230.         return;
  231.     if (check_crit (rr -> rr_recip_certificate_crit, mask, qp,
  232.             adr, "rr_recip_certificate_crit") == NOTOK)
  233.         return;
  234.     if (check_crit (rr -> rr_report_origin_authentication_check_crit, 
  235.             mask, qp,
  236.             adr, "rr_report_origin_authentication_check_crit") == NOTOK)
  237.         return;
  238.  
  239.     ix = rr -> rr_per_recip_extensions;
  240.     while (ix != NULL) {
  241.         if (check_crit (ix -> ext_criticality, CRITICAL_SUBMISSION, 
  242.                 qp,
  243.                 adr, "rr_per_recip_extensions") == NOTOK)
  244.             return;
  245.         ix = ix -> ext_next;
  246.     }
  247. }
  248.  
  249.  
  250.  
  251.  
  252. static void check_q_crits (qp, adr)
  253. register Q_struct    *qp;
  254. register ADDR        *adr;
  255. {
  256.     char    mask = CRITICAL_SUBMISSION;
  257.     CHAN    *outchan = adr -> ad_outchan -> li_chan;
  258.     X400_Extension    *ix;
  259.  
  260.     if (lexequ (outchan -> ch_content_out, cont_p22) == 0)
  261.         mask = mask | CRITICAL_TRANSFER | CRITICAL_DELIVERY;
  262.     else if (outchan -> ch_access == CH_MTS)
  263.         mask = mask | CRITICAL_DELIVERY;
  264.  
  265.     if (check_crit (qp -> latest_time_crit, mask, qp,
  266.             adr, "latest_time") == NOTOK)
  267.         return;
  268.  
  269.     if (check_crit(qp -> recip_reassign_crit, mask, qp, adr,
  270.                "recipient reassignment") == NOTOK)
  271.         return;
  272.  
  273.     if (check_crit (qp -> dl_expansion_crit, mask, qp, adr,
  274.             "dl expansion") == NOTOK)
  275.         return;
  276.     if (check_crit (qp -> conversion_with_loss_crit, mask, qp, 
  277.             adr, "conversion_with_loss") == NOTOK)
  278.         return;
  279.  
  280.     if (check_crit (qp -> content_correlator_crit, mask, qp, adr,
  281.             "content_correlator") == NOTOK)
  282.         return;
  283.  
  284.     if (check_crit(qp -> originator_return_address_crit, mask, qp, 
  285.                adr, "originator_return_address") == NOTOK)
  286.         return;
  287.     if (check_crit(qp -> forwarding_request_crit, mask, qp, adr,
  288.                "forwarding_request") == NOTOK)
  289.         return;
  290.  
  291.     if (check_crit(qp -> originator_certificate_crit, mask, qp, 
  292.                adr, "originator_certificate") == NOTOK)
  293.         return;
  294.  
  295.     if (check_crit(qp -> algorithm_identifier_crit, mask, qp, 
  296.                adr, "algorithm_identifier") == NOTOK)
  297.         return;
  298.  
  299.     if (check_crit(qp -> message_origin_auth_check_crit, mask, qp, 
  300.                adr, "message_origin_auth_check") == NOTOK)
  301.         return;
  302.     if (check_crit(qp -> security_label_crit, mask, qp, adr,
  303.                "security_label") == NOTOK)
  304.         return;
  305.  
  306.     if (check_crit(qp -> proof_of_submission_crit, mask, qp, adr,
  307.                "proof_of_submission") == NOTOK)
  308.         return;
  309.  
  310.     if (check_crit (qp -> dl_expansion_history_crit, mask, qp, 
  311.             adr, "dl_expansion_history") == NOTOK)
  312.         return;
  313.  
  314.     /* now do addr crits */
  315.     if (check_crit( adr -> ad_orig_req_alt_crit, mask, qp, adr,
  316.                "ad_orig_req_alt") == NOTOK)
  317.         return;
  318.  
  319.     if (check_crit (adr -> ad_req_del_crit, mask, qp, adr, 
  320.             "ad_req_del_crit") == NOTOK)
  321.         return;
  322.  
  323.     if (check_crit (adr -> ad_phys_forward_crit, mask, qp, adr,
  324.             "ad_phys_forward") == NOTOK)
  325.         return;
  326.  
  327.     if (check_crit (adr -> ad_phys_fw_ad_crit, mask, qp, adr,
  328.             "ad_phys_fw_ad") == NOTOK)
  329.         return;
  330.  
  331.     if (check_crit (adr -> ad_phys_modes_crit, mask, qp, adr,
  332.             "ad_phys_modes") == NOTOK)
  333.         return;
  334.  
  335.     if (check_crit (adr -> ad_reg_mail_type_crit, mask, qp, adr,
  336.             "ad_reg_mail_type") == NOTOK)
  337.         return;
  338.  
  339.     if (check_crit (adr -> ad_recip_number_for_advice_crit, mask, qp, 
  340.             adr, "ad_recip_number_for_advice") == NOTOK)
  341.         return;
  342.  
  343.     if (check_crit (adr -> ad_phys_rendition_attribs_crit, mask, qp, 
  344.             adr, "ad_phys_rendition_attribs") == NOTOK)
  345.         return;
  346.  
  347.     if (check_crit (adr -> ad_pd_report_request_crit, mask, qp, 
  348.             adr, "ad_pd_report_request") == NOTOK)
  349.         return;
  350.  
  351.     if (check_crit (adr -> ad_redirection_history_crit, mask, qp, 
  352.             adr, "ad_redirection_history") == NOTOK)
  353.         return;
  354.  
  355.     if (check_crit (adr -> ad_message_token_crit, mask, qp, adr,
  356.             "ad_message_token") == NOTOK)
  357.         return;
  358.  
  359.     if (check_crit (adr -> ad_content_integrity_crit, mask, qp, 
  360.             adr, "ad_content_integrity") == NOTOK)
  361.         return;
  362.  
  363.     if (check_crit (adr -> ad_proof_delivery_crit, mask, qp, adr,
  364.             "ad_proof_delivery") == NOTOK)
  365.         return;
  366.  
  367.     ix = adr -> ad_per_recip_ext_list;
  368.     while (ix != NULL) {
  369.         if (check_crit (ix -> ext_criticality, CRITICAL_SUBMISSION, qp,
  370.                 adr, "ad_per_recip_ext") == NOTOK)
  371.             return;
  372.         ix = ix -> ext_next;
  373.     }
  374.  
  375. }
  376.  
  377.  
  378.  
  379.  
  380. static void check_extn_crits (qp, ix, buf)
  381. Q_struct        *qp;
  382. register X400_Extension    *ix;
  383. char            *buf;
  384. {
  385.     while (ix != NULL) {
  386.         if (check_crit(ix -> ext_criticality, CRITICAL_SUBMISSION, 
  387.                    qp, NULLADDR, buf) == NOTOK)
  388.             return;
  389.         ix = ix -> ext_next;
  390.     }
  391. }
  392.  
  393. void check_report_level (qp)
  394. Q_struct    *qp;
  395. {
  396.     /* see x.411 12.2.1.1.18 */
  397.     ADDR    *ix;
  398.  
  399.     /* bad code relies on having same mapping into integers */
  400.     /* see adr.h usrreq and mtareq declarations */
  401.  
  402.     for (ix = qp->Raddress; ix; ix = ix -> ad_next)
  403.         if (ix -> ad_mtarreq < ix -> ad_usrreq)
  404.             ix -> ad_mtarreq = ix -> ad_usrreq;
  405. }
  406.  
  407. static CHAN    *getsplitter ()
  408. {
  409.     register CHAN    *spltr, **chp;
  410.  
  411.     for (chp = ch_all; 
  412.          (spltr = *chp) != NULLCHAN;
  413.          chp++)
  414.         if (spltr -> ch_chan_type == CH_SPLITTER)
  415.             return spltr;
  416.     return NULLCHAN;
  417. }
  418.  
  419. static int    must_solo_proc(ad)
  420. register ADDR    *ad;
  421. {
  422.     register LIST_RCHAN    *ix;
  423.     if (!ad->ad_resp)
  424.         return FALSE;
  425.     
  426.     if (ad->ad_outchan
  427.         && ad->ad_outchan->li_chan
  428.         && ad->ad_outchan->li_chan->ch_solo_proc == YES)
  429.         return TRUE;
  430.     
  431.     for (ix = ad->ad_fmtchan; ix != NULLIST_RCHAN; ix = ix -> li_next)
  432.         if (ix -> li_chan
  433.             && ix -> li_chan -> ch_solo_proc == YES)
  434.             return TRUE;
  435.     return FALSE;
  436. }
  437.  
  438. static void    replace_with_splitter (ad, spltr)
  439. register ADDR *ad;
  440. CHAN    *spltr;
  441. {
  442.     list_rchan_free (ad->ad_fmtchan);
  443.     ad->ad_fmtchan = NULLIST_RCHAN;
  444.     ad->ad_outchan->li_chan = spltr;
  445.     if (ad->ad_outchan->li_auth
  446.         && ad->ad_outchan->li_auth->chan)
  447.         ad->ad_outchan->li_auth->chan->li_chan = spltr;
  448. }
  449.     
  450. void check_splitter (qp)
  451. Q_struct    *qp;
  452. {
  453.     CHAN    *spltr;
  454.     register ADDR    *ix;
  455.     int    count;
  456.     if ((spltr = getsplitter()) == NULLCHAN)
  457.         return;
  458.  
  459.     for (count = 0, ix = qp->Raddress;
  460.          ix != NULLADDR && count < 2;
  461.          ix = ix -> ad_next) 
  462.         if (must_solo_proc (ix) == TRUE)
  463.             count++;
  464.  
  465.     if (count < 2)
  466.         return;
  467.  
  468.     /* have to replace some with splitter */
  469.  
  470.     for (ix = qp->Raddress;
  471.          ix != NULLADDR;
  472.          ix = ix -> ad_next) {
  473.         if (must_solo_proc (ix) == TRUE)
  474.             replace_with_splitter(ix, spltr);
  475.     }
  476. }
  477.             
  478.     
  479.